﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace FreesenseSubAIS.Core
{
   public class SideLight
    {
        public System.IO.Ports.SerialPort serialPort1;
        private static byte address = 0;
        /// <summary>
        /// 侧光源
        /// </summary>
        /// <param name="comStr"></param>
        public SideLight(string comStr)
        {
            try
            {
                serialPort1 = new System.IO.Ports.SerialPort(comStr);
                serialPort1.BaudRate = 19200;
                serialPort1.DataBits = 8;
                serialPort1.WriteTimeout = 3000;
                serialPort1.StopBits = System.IO.Ports.StopBits.One;
                serialPort1.Open();
                SetCONSTOnOff(1,1);
                Thread.Sleep(300);
                SetChMultipier(1,10);
                Thread.Sleep(300);
                SetCONSTOnOff(2, 1);
                Thread.Sleep(300);
                SetChMultipier(2, 10);
                Thread.Sleep(300);
                SetConstInt(1,0);
            }
            catch (Exception ex)
            {
                BpjbCommon.Net.Core.BpEventHandler.ErrHandler(string.Format ("错误消息：侧光源串口 {0} 连接失败！\r\n解决方法:\r\n1.检查设备是否运行正常。\r\n2.检查通信串口是否配置正确。\n",comStr )+ex.Message, BpjbCommon.Net.Core.ErrType.Warning);
            }
        }
        /// <summary>
        /// 背光源
        /// </summary>
        /// <param name="comStr"></param>
        /// <param name="s"></param>
        public SideLight(string comStr, int s)
        {
            try
            {
                serialPort1 = new System.IO.Ports.SerialPort(comStr);
                serialPort1.BaudRate = 9600;
                serialPort1.DataBits = 8;
                serialPort1.WriteTimeout = 3000;
                serialPort1.StopBits = System.IO.Ports.StopBits.One;
                serialPort1.Open();
            }
            catch (Exception ex)
            {
                throw new ArgumentException(ex.Message);
            }
        }
        public void CloseCom()
        {
            if (serialPort1 != null && serialPort1.IsOpen)
            {
                serialPort1.Close();
                serialPort1 = null;
            }
        }

        #region 侧光源
        private byte rs232_write(byte[] str)
        {
            if (serialPort1 != null && serialPort1.IsOpen)
                serialPort1.Write(str, 0, str.Length);
            else
            {
                return 0;
                throw new ArgumentException("串口连接失败！");
            }
            return 0;
        }
        /// <summary>
        /// 常亮模式控制侧光源开关
        /// </summary>
        /// <param name="sCH">通道号</param>
        /// <param name="sOn">开关信号On = 1,Off = 0</param>
        /// <returns></returns>
        public byte SetCONSTOnOff(byte sCH, byte sOn)
        {
            byte no_of_data = 6;
            byte[] str = new byte[no_of_data];
            str[0] = no_of_data;
            str[1] = address;
            str[2] = 0x12;
            str[3] = (byte)(1 << (sCH - 1));
            str[4] = sOn;
            str[5] = checksum(str);

            if (rs232_write(str) == 0)
                return 0;
            else
                return 1;
        }
        /// <summary>
        /// 校验和
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private byte checksum(byte[] str)
        {
            byte chk_sum = 0;

            for (int i = 0; i < str[0] - 1; i++)
                chk_sum ^= str[i];

            return chk_sum;
        }
        /// <summary>
        /// 设置通道运行模式
        /// </summary>
        /// <param name="sCH">通道号</param>
        /// <param name="sMode">0 => Constant，1 => Trigger， 3 => Auto Strobe</param>
        /// <returns></returns>
        public byte SetCHMode(byte sCH, byte sMode)
        {
            byte no_of_data = 6;
            byte[] str = new byte[no_of_data];
            str[0] = no_of_data;
            str[1] = address;
            str[2] = 0x11;
            str[3] = (byte)(1 << (sCH - 1));
            str[4] = sMode;
            str[5] = checksum(str);

            if (rs232_write(str) == 0)
                return 0;
            else
                return 1;
        }
        /// <summary>
        /// 设置侧光源倍率
        /// </summary>
        /// <param name="sCH"></param>
        /// <param name="sMul">1–10，1 = 10% of Max Current (Default)，10=100%</param>
        /// <returns></returns>
        public byte SetChMultipier(byte sCH, byte sMul)
        {
            byte no_of_data = 6;
            byte[] str = new byte[no_of_data];
            str[0] = no_of_data;
            str[1] = address;
            str[2] = 0x10;
            str[3] = (byte)(1 << (sCH - 1));
            str[4] = sMul;
            str[5] = checksum(str);

            if (rs232_write(str) == 0)
                return 0;
            else
                return 1;
        }
        /// <summary>
        /// 改变光源强度
        /// </summary>
        /// <param name="sCH">通道号</param>
        /// <param name="sInt">光强度(Range = 0-255)</param>
        /// <returns></returns>
        public byte SetConstInt(byte sCH, byte sInt)
        {
            byte no_of_data = 6;
            byte[] str = new byte[no_of_data];
            str[0] = no_of_data;
            str[1] = address;
            str[2] = 0x13;
            str[3] = (byte)(1 << (sCH - 1));
            str[4] = sInt;
            str[5] = checksum(str);

            if (rs232_write(str) == 0)
                return 0;
            else
                return 1;
        }
        #endregion 侧光源

        #region 背光
        /// <summary>
        /// 打开通道光源
        /// </summary>
        /// <param name="sCH">0x01-1通道，0x02-2通道</param>
        /// <returns></returns>
        public byte OpenPower(byte sCH)
        {
            //帧头   命令      帧长              帧长校验      数据    异或校验和
            //1字节  1字节     1字节             1 字节        N 字节  1 字节
            //0xFE   参见定义  数据长度，最大50  字节帧长取反  无        数据校验和
            //FE     0B        01                FE            01      FE
            //                 01为通道1                       数据01
            byte temp;
            byte no_of_data = 6;
            byte[] str = new byte[no_of_data];
            str[0] = 0xFE;
            str[1] = 0x0B;
            str[2] = 0x01;
            temp = (byte)(~(str[2]));
            str[3] = 0xFE;
            str[4] = sCH;
            str[5] = 0xFE;
            if (rs232_write(str) == 0)
                return 0;
            else
                return 1;
        }
        public byte ClosePower(byte sCH)
        {
            //帧头   命令      帧长              帧长校验      数据    异或校验和
            //1字节  1字节     1字节             1 字节        N 字节  1 字节
            //0xFE   参见定义  数据长度，最大50  字节帧长取反  无        数据校验和
            //FE     0C        01                FE            01      FE
            //                 01为通道1                       数据01
            byte temp;
            byte no_of_data = 6;
            byte[] str = new byte[no_of_data];
            str[0] = 0xFE;
            str[1] = 0x0C;
            str[2] = 1;
            temp = (byte)(~(str[2]));
            str[3] = 0xFE;
            str[4] = sCH;
            str[5] = 0xFE;
            if (rs232_write(str) == 0)
                return 0;
            else
                return 1;
        }
        public byte SetGrade(byte sCH, byte sIn)
        {
            byte temp;
            byte sum = 0;
            byte[] COMframedata = new byte[256];
            sum = 0;
            COMframedata[0] = 0xFE;
            COMframedata[1] = 0x0E;
            COMframedata[2] = 2;
            temp = (byte)(~(COMframedata[2]));
            COMframedata[3] = temp;
            COMframedata[4] = 1;
            COMframedata[5] = sIn;//亮度
            sum ^= COMframedata[4];
            sum ^= COMframedata[5];
            COMframedata[6] = sum;
            if (rs232_write(COMframedata) == 0)
                return 0;
            else
                return 1;
        }
        public byte SetTiggerMode(byte sCH, bool sIn)
        {
            byte temp;

            byte[] COMframedata = new byte[256];
            COMframedata[0] = 0xFE;
            COMframedata[1] = 0x84;
            COMframedata[2] = 1;
            temp = (byte)(~(COMframedata[2]));
            COMframedata[3] = temp;
            if (sIn)
                COMframedata[4] = 1;
            else
                COMframedata[4] = 0;
            COMframedata[5] ^= COMframedata[4];
            if (rs232_write(COMframedata) == 0)
                return 0;
            else
                return 1;
        }
        #endregion 背光
    }
}
